﻿using SL651Center2.x.Enums;
using SL651Center2.x.Messages;
using TouchSocket.Core;

namespace SL651Center2.x.ReadMessage
{
    public class ReadHEXData
    {
        public static ReadHEXData Instance { get; } = new ReadHEXData();

        private ReadHEXData()
        {
            _bytes = new List<byte>();
        }

        readonly List<byte> _bytes;

        public IMessage Message { get; private set; }

        public void ReadHEXMessage(in ByteBlock byteBlock, FunctionCode functionCode)
        {
            switch (functionCode)
            {
                case FunctionCode.FC_30:
                case FunctionCode.FC_32:
                case FunctionCode.FC_33:
                case FunctionCode.FC_34://小时报
                case FunctionCode.FC_37:
                case FunctionCode.FC_3A:
                case FunctionCode.FC_44:
                    //要素数据
                    {
                        MessageElement message = new MessageElement();
                        message.Read(byteBlock);
                        Message = message;
                        break;
                    }
                case FunctionCode.FC_31://有时间步长码
                case FunctionCode.FC_38://有时间步长码
                    //均匀时段报
                    {
                        MessageTime messageTime = new MessageTime();
                        messageTime.Read(byteBlock);
                        Message = messageTime;
                        break;
                    }
                case FunctionCode.FC_35:
                case FunctionCode.FC_39:
                    //人工置数报
                    {
                        var tt1 = byteBlock.ReadByte();
                        if (tt1 == 0xF2)
                        {
                            Console.WriteLine("人工置数");
                        }
                        byteBlock.ReadByte();

                        int con = byteBlock.Length - 10;
                        var datab = byteBlock.ToArray(byteBlock.Position, con);
                        var datastr = datab.ToASCIIString();
                        Console.WriteLine(datastr);

                        var arr = datastr.Split(" ");
                        for (int i = 0; i < arr.Length - 1; i += 2)
                        {
                            var (n, un) = ManualEntryInfo.GetInfo(arr[i]);
                            Console.WriteLine($"名称：{n},数据：{arr[i + 1]}{un}");
                        }

                        break;
                    }
                case FunctionCode.FC_36:
                    //图片
                    {
                        MessageImg messageImg = new MessageImg();
                        messageImg.Read(byteBlock);
                        Message = messageImg;

                        /*var serialnum = byteBlock.ReadToArray(2);
                        var snum = Helper.ToHEXString(serialnum);
                        Console.WriteLine($"流水号:{Convert.ToUInt16(snum, 16)}-{snum}");

                        var timeHEX = BitConverter.ToString(byteBlock.ReadToArray(6));
                        var timearr = timeHEX.Split('-');
                        var timeString = $"{timearr[0]}年{timearr[1]}月{timearr[2]}日{timearr[3]}:{timearr[4]}:{timearr[5]}";
                        Console.WriteLine($"发报时间:{timeString}");

                        var code = byteBlock.ReadToArray(1);
                        if (code[0] == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = byteBlock.ReadToArray(5);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        Console.WriteLine($"遥测站分类码:{Helper.ToHEXString(byteBlock.ReadToArray(1))}");

                        var tt2 = byteBlock.ReadToArray(1);
                        if (tt2[0] == 0xf0)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var tHEX = BitConverter.ToString(byteBlock.ReadToArray(5));
                            var tarr = tHEX.Split('-');
                            var tString = $"{tarr[0]}年{tarr[1]}月{tarr[2]}日{tarr[3]}:{tarr[4]}";
                            Console.WriteLine($"观测时间:{tString}");
                        }
                        else
                        {
                            Console.WriteLine("观测时间引导符错误");
                        }

                        var elemCode = byteBlock.ReadToArray(1)[0];

                        if (elemCode != 0x03 && elemCode != 0x17)
                        {
                            //跳过数据定义
                            //byteBlock.Seek(1, SeekOrigin.Current);
                            _ = byteBlock.ReadToArray(1);

                            var (name, unit) = ElementInfo.Instance.GetInfo((ElementCode)elemCode);

                            Console.WriteLine(name);

                            //图片信息
                            if ((ElementCode)elemCode == ElementCode.PIC)
                            {
                                var img = byteBlock.ToArray(byteBlock.Pos);

                                Console.WriteLine(Helper.ByteToImg(img));
                            }
                        }*/

                    }
                    break;
                case FunctionCode.FC_40:
                case FunctionCode.FC_41:
                    //基本配置表
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        Console.WriteLine($"遥测站分类码:{Helper.ToHEXString(byteBlock.ReadByte())}");

                        //读取一个标识符
                        var elemCode = byteBlock.ReadByte();
                        while (byteBlock.Position < byteBlock.Length - 3)
                        {
                            //读取数据定义
                            var dlen = byteBlock.ReadByte();
                            var dalen = dlen >> 3;//字节数
                            var dalen1 = dlen & 0x07;//小数位数
                            Console.WriteLine($"数据定义:{dlen},字节数:{dalen},小数位数:{dalen1}");
                            switch (elemCode)
                            {
                                //中心站地址
                                case 0x01:
                                    {
                                        var centers = new byte[4];
                                        byteBlock.Read(centers);
                                        Console.WriteLine($"中心站1地址：{centers[0]}");
                                        Console.WriteLine($"中心站2地址：{centers[1]}");
                                        Console.WriteLine($"中心站3地址：{centers[2]}");
                                        Console.WriteLine($"中心站4地址：{centers[3]}");
                                    }
                                    break;
                                //遥测站地址
                                case 0x02:
                                    {
                                        var f = new byte[5];
                                        byteBlock.Read(f);
                                        var siteCode1 = Helper.ToHEXString(f);
                                        Console.WriteLine($"遥测站地址:{siteCode1}");
                                        break;
                                    }
                                //密码
                                case 0x03:
                                    {
                                        var pwd = new byte[2];
                                        byteBlock.Read(pwd);
                                        Console.WriteLine($"密码:{Helper.ToHEXString(pwd)}");
                                        break;
                                    }
                                //中心站1主信道类型及地址
                                case 0x04:
                                    {
                                        Console.WriteLine("中心站1主信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //中心站1备用信道类型及地址
                                case 0x05:
                                    {
                                        Console.WriteLine("中心站1备用信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //中心站2主信道类型及地址
                                case 0x06:
                                    {
                                        Console.WriteLine("中心站2主信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //中心站2备用信道类型及地址
                                case 0x07:
                                    {
                                        Console.WriteLine("中心站2备用信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //中心站3主信道类型及地址
                                case 0x08:
                                    {
                                        Console.WriteLine("中心站3主信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //中心站3备用信道类型及地址
                                case 0x09:
                                    {
                                        Console.WriteLine("中心站3备用信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //中心站4主信道类型及地址
                                case 0x0A:
                                    {
                                        Console.WriteLine("中心站4主信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //中心站4备用信道类型及地址
                                case 0x0B:
                                    {
                                        Console.WriteLine("中心站4备用信道类型及地址：");
                                        var xindao = byteBlock.ReadByte();
                                        var xin = Helper.ByteToBCDInt(xindao);
                                        //地址
                                        var addr = new byte[dalen - 1];
                                        if (xin == 0)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-禁用");
                                        }
                                        else if (xin == 1)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-短信");
                                            var ip = new byte[6];
                                            byteBlock.Read(ip);
                                            var port = new byte[3];
                                            byteBlock.Read(port);
                                            Console.WriteLine($"{Helper.ByteToBCDInt(ip)}:{Helper.ByteToBCDInt(port)}");
                                        }
                                        else if (xin == 2)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-IPV4");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 3)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-北斗");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 4)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-海事卫星");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 5)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-PSTN");
                                            byteBlock.Read(addr);
                                        }
                                        else if (xin == 6)
                                        {
                                            Console.WriteLine($"信道类型：{xin}-超短波");
                                            byteBlock.Read(addr);
                                        }
                                        break;
                                    }
                                //工作方式
                                case 0x0C:
                                    {
                                        var workType = byteBlock.ReadByte();
                                        var wt = Helper.ByteToBCDInt(workType);
                                        if (wt == 1)
                                        {
                                            Console.WriteLine($"工作方式:{wt}-自报工作状态");
                                        }
                                        else if (wt == 2)
                                        {
                                            Console.WriteLine($"工作方式:{wt}-自报确认工作状态");
                                        }
                                        else if (wt == 3)
                                        {
                                            Console.WriteLine($"工作方式:{wt}-查询/应答工作状态");
                                        }
                                        else if (wt == 4)
                                        {
                                            Console.WriteLine($"工作方式:{wt}-调试或维修状态");
                                        }
                                        break;
                                    }
                                //遥测站采集要素设置
                                case 0x0D:
                                    {
                                        var a1 = byteBlock.ReadByte();
                                        var a1bin = Helper.ByteToBinString(a1);
                                        var a1str = $"降水量：{a1bin[0]}，蒸发量：{a1bin[1]}，风向：{a1bin[2]}，风速：{a1bin[3]}，气温：{a1bin[4]}，湿度：{a1bin[5]}，地温：{a1bin[6]}，气压：{a1bin[7]}";
                                        Console.WriteLine(a1str);

                                        var a2 = byteBlock.ReadByte();
                                        var a2bin = Helper.ByteToBinString(a2);
                                        var a2str = $"水位8：{a2bin[0]}，水位7：{a2bin[1]}，水位6：{a2bin[2]}，水位5：{a2bin[3]}，水位4：{a2bin[4]}，水位3：{a2bin[5]}，水位2：{a2bin[6]}，水位1：{a2bin[7]}";
                                        Console.WriteLine(a2str);

                                        var a3 = byteBlock.ReadByte();
                                        var a3bin = Helper.ByteToBinString(a3);
                                        var a3str = $"地下水埋深：{a3bin[0]}，图片：{a3bin[1]}，波浪：{a3bin[2]}，闸门开度：{a3bin[3]}，水量：{a3bin[4]}，流速：{a3bin[5]}，流量：{a3bin[6]}，水压：{a3bin[7]}";
                                        Console.WriteLine(a3str);

                                        var a4 = byteBlock.ReadByte();
                                        var a4bin = Helper.ByteToBinString(a4);
                                        var a4str = $"水表8：{a4bin[0]}，水表7：{a4bin[1]}，水表6：{a4bin[2]}，水表5：{a4bin[3]}，水表4：{a4bin[4]}，水表3：{a4bin[5]}，水表2：{a4bin[6]}，水表1：{a4bin[7]}";
                                        Console.WriteLine(a4str);

                                        var a5 = byteBlock.ReadByte();
                                        var a5bin = Helper.ByteToBinString(a5);
                                        var a5str = $"100厘米墒情：{a5bin[0]}，80厘米墒情：{a5bin[1]}，60厘米墒情：{a5bin[2]}，50厘米墒情：{a5bin[3]}，40厘米墒情：{a5bin[4]}，30厘米墒情：{a5bin[5]}，20厘米墒情：{a5bin[6]}，10厘米墒情：{a5bin[7]}";
                                        Console.WriteLine(a5str);

                                        var a6 = byteBlock.ReadByte();
                                        var a6bin = Helper.ByteToBinString(a6);
                                        var a6str = $"pH值：{a6bin[0]}，溶解氧：{a6bin[1]}，电导率：{a6bin[2]}，浊度：{a6bin[3]}，氧化还原电位：{a6bin[4]}，高猛酸盐指数：{a6bin[5]}，氨氮：{a6bin[6]}，水温：{a5bin[7]}";
                                        Console.WriteLine(a6str);

                                        var a7 = byteBlock.ReadByte();
                                        var a7bin = Helper.ByteToBinString(a7);
                                        var a7str = $"总有机碳：{a7bin[0]}，总氮：{a7bin[1]}，总磷：{a7bin[2]}，锌：{a7bin[3]}，硒：{a7bin[4]}，砷：{a7bin[5]}，总汞：{a7bin[6]}，镉：{a7bin[7]}";
                                        Console.WriteLine(a6str);

                                        var a8 = byteBlock.ReadByte();
                                        var a8bin = Helper.ByteToBinString(a8);
                                        var a8str = $"{a8bin[0]}，{a8bin[1]}，{a8bin[2]}，{a8bin[3]}，{a8bin[4]}，叶绿素a：{a8bin[5]}，铜：{a8bin[6]}，铅：{a8bin[7]}";
                                        Console.WriteLine(a6str);

                                        break;
                                    }
                                //中继站(集合转发站)服务地址范围
                                case 0x0E:
                                    {

                                        //var l = BitConverter.ToUInt16(dlen);
                                        var addr = new byte[dlen];
                                        byteBlock.Read(addr);
                                        for (int i = 0; i < addr.Length; i += 6)
                                        {
                                            var start = addr.Skip(i).Take(6).ToArray();
                                            var num = start.Last();
                                            Console.WriteLine($"起始地址：{Helper.ToHEXString(start[0..5])},站数：{Helper.ByteToBCDInt(num)}");
                                        }
                                        break;
                                    }
                                //遥测站通信设备识别号
                                case 0x0F:
                                    {
                                        var sim = byteBlock.ReadByte();
                                        var st = Helper.ByteToBCDInt(sim);
                                        if (st == 1)
                                        {
                                            Console.WriteLine($"卡类型：{st}-移动通信卡");
                                        }
                                        else if (st == 2)
                                        {
                                            Console.WriteLine($"卡类型：{st}-北斗卫星通信卡");
                                        }
                                        var simcode = new byte[dalen - 1];
                                        byteBlock.Read(simcode);
                                        Console.WriteLine($"卡识别号：{Helper.ToHEXString(simcode)}");

                                        break;
                                    }
                                default:
                                    break;
                            }

                            //读取下一个标识符
                            elemCode = byteBlock.ReadByte();
                        }
                    }
                    break;
                case FunctionCode.FC_42:
                case FunctionCode.FC_43:
                    //运行参数表
                    {
                        MessageRunConfig message = new MessageRunConfig();
                        message.Read(byteBlock);
                        Message = message;

                        break;
                    }
                case FunctionCode.FC_45:
                    //软件版本
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        var vr = byteBlock.ReadByte();
                        var vrinfo = new byte[vr];
                        byteBlock.Read(vrinfo);

                        break;
                    }
                case FunctionCode.FC_46:
                case FunctionCode.FC_4B:
                    //遥测站状态和报警信息
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        var elemCode = byteBlock.ReadByte();
                        var (name, unit) = ElementInfo.Instance.GetInfo((ElementCode)elemCode);
                        Console.WriteLine(name);
                        if (elemCode == (byte)ElementCode.ZT)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var tHEX = new byte[4];
                            byteBlock.Read(tHEX);
                            string binStr = Helper.ByteToBinString(tHEX);
                            var str = binStr.ToCharArray();
                            Array.Reverse(str);
                            Console.WriteLine(binStr);

                            if (str[0] == '0')
                            {
                                Console.WriteLine($"交流电充电状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("交流电充电状态：停电");
                            }
                            if (str[1] == '0')
                            {
                                Console.WriteLine("蓄电池电压状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("蓄电池电压状态：电压低");
                            }
                            if (str[2] == '0')
                            {
                                Console.WriteLine("水位超限报警状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("水位超限报警状态：报警");
                            }
                            if (str[3] == '0')
                            {
                                Console.WriteLine("流量超限报警状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("流量超限报警状态：报警");
                            }
                            if (str[4] == '0')
                            {
                                Console.WriteLine("水质超限报警状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("水质超限报警状态：报警");
                            }
                            if (str[5] == '0')
                            {
                                Console.WriteLine("流量仪表状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("流量仪表状态：故障");
                            }
                            if (str[6] == '0')
                            {
                                Console.WriteLine("水位仪表状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("水位仪表状态：故障");
                            }
                            if (str[7] == '0')
                            {
                                Console.WriteLine("终端箱门状态：开启");
                            }
                            else
                            {
                                Console.WriteLine("终端箱门状态：关闭");
                            }
                            if (str[8] == '0')
                            {
                                Console.WriteLine("存储器状态：正常");
                            }
                            else
                            {
                                Console.WriteLine("存储器状态：异常");
                            }
                            if (str[9] == '0')
                            {
                                Console.WriteLine("IC卡功能有效：关闭");
                            }
                            else
                            {
                                Console.WriteLine("IC卡功能有效：IC卡有效");
                            }
                            if (str[10] == '0')
                            {
                                Console.WriteLine("水泵工作状态：水泵工作");
                            }
                            else
                            {
                                Console.WriteLine("水泵工作状态：水泵停机");
                            }
                            if (str[11] == '0')
                            {
                                Console.WriteLine("剩余水量报警：未超限");
                            }
                            else
                            {
                                Console.WriteLine("剩余水量报警：水量超限");
                            }

                        }
                        break;
                    }
                case FunctionCode.FC_47://初始化固态存储数据
                case FunctionCode.FC_48://恢复出厂设置
                case FunctionCode.FC_4A://设置遥测站时钟
                case FunctionCode.FC_51://查询遥测站时钟
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }
                        break;
                    }
                case FunctionCode.FC_49:
                    //修改密码
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        var elemCode = byteBlock.ReadByte();
                        if (elemCode == 0x03)
                        {
                            var pwd = byteBlock.ReadInt16(EndianType.Big);
                            Console.WriteLine($"新密码:{pwd}");
                        }
                        break;
                    }
                case FunctionCode.FC_4C:
                    //水泵状态
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        var l = byteBlock.ReadByte();
                        var bl = new byte[l];
                        byteBlock.Read(bl);
                        var bs = Helper.ByteToBinString(bl);
                        var str = bs.ToCharArray();
                        Array.Reverse(str);
                        for (int i = 0; i < str.Length; i++)
                        {
                            string t = str[i] == '0' ? "关闭" : "开启";
                            Console.Write($"{i + 1}号水泵状态：{str[i]}-{t}");
                        }
                        break;
                    }
                case FunctionCode.FC_4D:
                    //阀门状态
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        var l1 = byteBlock.ReadByte();
                        var bl1 = new byte[l1];
                        byteBlock.Read(bl1);
                        var bs1 = Helper.ByteToBinString(bl1);
                        var str = bs1.ToCharArray();
                        Array.Reverse(str);
                        for (int i = 0; i < str.Length; i++)
                        {
                            string t = str[i] == '0' ? "关闭" : "开启";
                            Console.Write($"{i + 1}号阀门状态：{str[i]}-{t}");
                        }
                        break;
                    }
                case FunctionCode.FC_4E:
                    //闸门状态
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        var jl = byteBlock.ReadByte();
                        var j1 = jl / 8;
                        if (j1 % 8 != 0)
                        {
                            j1 += 1;
                        }
                        var jm = new byte[j1];
                        byteBlock.Read(jm);
                        var jms = Helper.ByteToBinString(jm);
                        var str = jms.ToCharArray();
                        Array.Reverse(str);
                        for (int i = 0; i < str.Length; i++)
                        {
                            string t = str[i] == '0' ? "关闭" : "开启";
                            Console.Write($"{i + 1}号闸门状态：{str[i]}-{t}");
                        }

                        for (int i = 0; i < jl; i++)
                        {
                            var kd = new byte[2];
                            byteBlock.Read(kd);
                            var v = Helper.ByteToBCDInt(kd);
                            Console.WriteLine($"{i + 1}号闸门开度：{v}");
                        }

                        break;
                    }
                case FunctionCode.FC_4F:
                    //水量定值
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        var cz = byteBlock.ReadByte();
                        if (cz == 0xFF)
                        {
                            Console.WriteLine("定值控制投入");
                        }
                        else if (cz == 0x00)
                        {
                            Console.WriteLine("定值控制退出");
                        }
                        break;
                    }
                case FunctionCode.FC_50:
                    //遥测站事件记录
                    {
                        var code = byteBlock.ReadByte();
                        if (code == 0xf1)
                        {
                            byteBlock.Seek(1, SeekOrigin.Current);
                            var f = new byte[5];
                            byteBlock.Read(f);
                            var siteCode1 = Helper.ToHEXString(f);
                            Console.WriteLine($"遥测站地址:{siteCode1}");
                        }
                        else
                        {
                            Console.WriteLine("测站地址引导符错误");
                        }

                        for (int i = 1; i < 33; i++)
                        {
                            switch (i)
                            {
                                case 1:
                                    var num1 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-历史数据初始化记录：{num1}");
                                    break;
                                case 2:
                                    var num2 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-参数变更记录：{num2}");
                                    break;
                                case 3:
                                    var num3 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-状态量变位记录：{num3}");
                                    break;
                                case 4:
                                    var num4 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-传感器及仪表故障记录：{num4}");
                                    break;
                                case 5:
                                    var num5 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-密码修改记录：{num5}");
                                    break;
                                case 6:
                                    var num6 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-终端故障记录：{num6}");
                                    break;
                                case 7:
                                    var num7 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-交流失电记录：{num7}");
                                    break;
                                case 8:
                                    var num8 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-蓄电池电压低告警记录：{num8}");
                                    break;
                                case 9:
                                    var num9 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-终端箱非法打开记录：{num9}");
                                    break;
                                case 10:
                                    var num10 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-水泵故障记录：{num10}");
                                    break;
                                case 11:
                                    var num11 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-剩余水量超限告警记录：{num11}");
                                    break;
                                case 12:
                                    var num12 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-水位超限告警记录：{num12}");
                                    break;
                                case 13:
                                    var num13 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-水压超限告警记录：{num13}");
                                    break;
                                case 14:
                                    var num14 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-水质参数超限告警记录：{num14}");
                                    break;
                                case 15:
                                    var num15 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-数据出错记录：{num15}");
                                    break;
                                case 16:
                                    var num16 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-发报文记录：{num16}");
                                    break;
                                case 17:
                                    var num17 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-收报文记录：{num17}");
                                    break;
                                case 18:
                                    var num18 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-发报文出错记录：{num18}");
                                    break;
                                default:
                                    var num19 = byteBlock.ReadUInt16(EndianType.Big);
                                    Console.WriteLine($"ERC{i}-：{num19}");
                                    break;
                            }
                        }

                        break;
                    }
                default:
                    break;

            }
        }

        public void ReadHEXMessage(in ByteBlock byteBlock, MessageFrame messageFrame)
        {
            //判断是否多包传输
            if (messageFrame.StartMark == StartMarks.SYN)
            {
                //读取正文
                var bytes = byteBlock.ToArray(byteBlock.Position, messageFrame.MessageLength);
                //将正文进行保存
                _bytes.AddRange(bytes);

                //如果是最后一个包
                if (messageFrame.PackageIndex == messageFrame.PackageCount)
                {
                    //创建字节块流
                    ByteBlock block = new ByteBlock(_bytes.Count);
                    //将正文数据写入
                    block.Write(_bytes.ToArray());
                    //设置游标到起始位置
                    block.SeekToStart();
                    //解析正文
                    ReadHEXMessage(block, messageFrame.FunctionCode);
                    //清除保存的正文
                    _bytes.Clear();
                    //释放字节流对象
                    block.Dispose();
                }
            }
            else
            {
                ReadHEXMessage(byteBlock, messageFrame.FunctionCode);
            }
        }

    }
}
